package org.feng.parser;

import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.feng.entity.FreeMarkerEntity;
import org.feng.entity.TableMetaData;
import org.feng.util.FreeMarkerUtil;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 模板渲染类
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年07月23日 11时14分
 */
public class TemplateProcessor {
    private static final String DEFAULT_TEMPLATE_NAME = "Entity.java.ftl";

    private final String templateName;
    private final FreeMarkerEntity freeMarkerEntity;

    public TemplateProcessor(String templateName, FreeMarkerEntity freeMarkerEntity) {
        Objects.requireNonNull(freeMarkerEntity);
        if (!StringUtils.hasText(templateName)) {
            templateName = DEFAULT_TEMPLATE_NAME;
        }
        this.templateName = templateName;
        this.freeMarkerEntity = freeMarkerEntity;
    }

    public TemplateProcessor(FreeMarkerEntity freeMarkerEntity) {
        this(null, freeMarkerEntity);
    }

    private Template load() {
        try {
            return FreeMarkerUtil.getConfiguration().getTemplate(templateName);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String process() {
        Map<String, Object> map = new HashMap<>(16);
        // 作者
        map.put("author", freeMarkerEntity.getAuthor());
        // 时间
        map.put("date", FreeMarkerEntity.date);
        // 版本
        map.put("version", freeMarkerEntity.getVersion());
        // 类文档注释
        map.put("classDoc", freeMarkerEntity.getClassDoc());
        TableMetaData tableMetaData = freeMarkerEntity.getTableMetaData();
        // 设置类名
        String className = freeMarkerEntity.getClassName();
        if (Objects.isNull(className)) {
            className = tableMetaData.toClassName();
        }
        map.put("className", className);
        // 设置是否使用lombok
        map.put("lombok", freeMarkerEntity.isLombok());
        map.put("lombokData", freeMarkerEntity.isLombok());
        map.put("lombokToString", freeMarkerEntity.isLombokToString());

        map.put("gson", freeMarkerEntity.isGson());
        map.put("fields", tableMetaData.getColumnInfos());
        map.put("jpa", freeMarkerEntity.isJpa());
        map.put("packageName", freeMarkerEntity.getPackageName());
        map.put("tableName", tableMetaData.getTableName());

        StringWriter stringWriter = new StringWriter();
        try {
            load().process(map, stringWriter);
        } catch (TemplateException | IOException e) {
            throw new RuntimeException(e);
        }
        return stringWriter.toString();
    }
}
